package com.yanqu.road.server.cmd.player;

import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.logic.bussiness.player.UserAttributeBussiness;
import com.yanqu.road.logic.bussiness.player.UserBussiness;
import com.yanqu.road.logic.bussiness.player.UserInteractiveBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.interactive.InteractiveRecord;
import com.yanqu.road.entity.interactive.UserInteractive;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.cmd.base.AbstractCommand;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.player.*;
import com.yanqu.road.server.manger.config.InteractiveMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.server.command.Cmd;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.Map;


@Cmd(code = Protocol.S_HATE_PLAYER, desc = "蛊惑")
public class HatePlayerCmd extends AbstractCommand {

	private long hateUserId;

	private int heartCount;
	private UserInfo hateUserInfo;
	private BigInteger effectValue = BigInteger.ZERO;
	private long hateServerId;
	private boolean needResponse;

	@Override
	public boolean parseData(YanQuMessage packet) throws Exception {
		PlayerProto.HatePlayerReqMsg reqMsg = PlayerProto.HatePlayerReqMsg.parseFrom(packet.getBytes());
		hateUserId = reqMsg.getUserId();
		hateServerId = reqMsg.getServerId();
		return true;
	}

	@Override
	public void execute(GamePlayer player, YanQuMessage packet) throws Exception {
		if(0 == hateServerId){
			hateServerId = GameServer.getInstance().getServerId();
		}
		if(hateServerId == GameServer.getInstance().getServerId()){
			localServerLogic(player);
		}else {
			crossServerLogic(player);
		}
	}

	private void localServerLogic(GamePlayer player){
		needResponse = true;
		hateUserInfo = UserMgr.getUserInfo(hateUserId);
		if(null == hateUserInfo){
			ret = GameErrorCode.E_USER_NO_FOUND;
			return;
		}

		// 先恢复下点赞值，否则会有误差
		UserMgr.autoRecoverHeart(hateUserInfo);

		GamePlayer hatePlayer = GamePlayerMgr.getOnlinePlayer(hateUserId);
		UserInteractive userInteractive = player.getModule(InteractiveModule.class).getUserInteractive();
		synchronized (hateUserInfo){
			if(userInteractive.hasHateUserId(hateUserId)){
				ret = GameErrorCode.E_HAS_HATE;
				return;
			}
			if ((hateUserInfo.getTitleId() - player.getTitleId()) >= GameConfig.TRICK_LEVEL_LOCK) {
				ret = GameErrorCode.E_HATE_TITLE_NO_ENOUGH;
				return;
			}
			if(hateUserInfo.getTodayBeHateTimes() >= GameConfig.ONE_DAY_PLAYER_BE_HATE_MAX_TIMES){
				ret = GameErrorCode.E_PLAYER_BE_HATE_MAX_TIMES;
				return;
			}
			int limitValue = InteractiveMgr.getBeHateLimit();
			heartCount = hateUserInfo.getHeartCount();
			if(heartCount <= limitValue){
				ret = GameErrorCode.E_PLAYER_CURRENT_HATE_LIMIT;
				return;
			}
			if(!player.getModule(CurrencyModule.class).removeCurrency(new Property(GameConfig.GAME_ITEM_HATE, BigInteger.ONE),
					eLogMoneyType.System, eLogMoneyType.HatePlayer)){
				ret = GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
				return;
			}
			heartCount--;
			hateUserInfo.setHeartCount(heartCount);
			hateUserInfo.setTodayBeHateTimes(hateUserInfo.getTodayBeHateTimes() + 1);
			effectValue = UserMgr.getHeartEffectEarnSpeed(hateUserInfo.getBaseEarnSpeed());
			if(null != hatePlayer){
				hatePlayer.getModule(AttributeModule.class).syncAttribute(ePlayerAttrType.HeartCount);
				//hatePlayer.getModule(EarnSpeedModule.class).scheduleAddSilver();
			}else {
				hateUserInfo.setEarnSpeed(hateUserInfo.getEarnSpeed().subtract(effectValue));
				//赚速榜
				RankMgr.changeUserRank(eBigRankType.Normal.getValue(), hateUserInfo.getUserId(), hateUserInfo.getEarnSpeed(), eRankType.EarnSpeed.getValue(), "");
			}
		}
		if(null != hatePlayer){
			//hatePlayer.getModule(AttributeModule.class).syncAttribute(ePlayerAttrType.HeartCount);
			hatePlayer.getModule(EarnSpeedModule.class).scheduleAddSilver();
		}
		if(-1 == heartCount){
			hateUserInfo.setLastHeartRecoverTime(System.currentTimeMillis() / 1000);
			if (null == hatePlayer) {
				UserBussiness.updateLastHeartRecoverTimeAndEarnSpeedAndHateTimes(hateUserId, heartCount, hateUserInfo.getLastHeartRecoverTime(), hateUserInfo.getEarnSpeed(),
						hateUserInfo.getTodayBeHateTimes());
			}
		}else {
			if (null == hatePlayer) {
				UserBussiness.updateHeartCountAndEarnSpeedAndHateTimes(hateUserId, heartCount, hateUserInfo.getEarnSpeed(), hateUserInfo.getTodayBeHateTimes());
			}
		}
		if(null == hatePlayer){
			UserAttributeBussiness.updateAddUserAttribute(hateUserId, ePlayerAttrType.TotalBeHateTimes, 1);
		}else {
			AttributeModule hateAttributeModule = hatePlayer.getModule(AttributeModule.class);
			hateAttributeModule.addAttribute(ePlayerAttrType.TotalBeHateTimes, 1);
			hatePlayer.notifyListener(eGamePlayerEventType.TotalBeHateTimes.getValue(), hateAttributeModule.getAttribute(ePlayerAttrType.TotalBeHateTimes));
		}
		userInteractive.addHateUserId(hateUserId);
		player.getModule(InteractiveModule.class).syncUserInteractive();
		InteractiveRecord interactiveRecord = UserMgr.initInteractiveRecord(hateUserId, eInteractiveType.hate.getValue(),
				player.getUserId(), UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId()));
		if(null != hatePlayer) {
			hatePlayer.getModule(InteractiveModule.class).addInteractiveRecord(interactiveRecord, effectValue);
		}else {
			UserInteractiveBussiness.addInteractiveRecord(interactiveRecord);
		}
	}

	private void crossServerLogic(GamePlayer player){
		needResponse = true;
		String unionUid = player.getUserInfo().getUnionUid();
		if(StringUtils.isNullOrEmpty(unionUid)){
			ret = GameErrorCode.E_UNION_NO_JOIN_UNION;
			return;
		}
		Map<Long, CrossUnionMember> memberMap = CrossUnionMgr.getUnionMemberMap(unionUid);
		if(!memberMap.containsKey(hateUserId)){
			ret = GameErrorCode.E_CANNOT_HATE_NO_SAME_UNION;
			return;
		}
		InteractiveModule interactiveModule = player.getModule(InteractiveModule.class);
		UserInteractive userInteractive = interactiveModule.getUserInteractive();
		if(userInteractive.hasHateUserId(hateUserId)){
			ret = GameErrorCode.E_HAS_HATE;
			return;
		}
		if(interactiveModule.isOpHateUser(hateUserId)){
			ret = GameErrorCode.E_IS_CROSS_HATE_PLAYER;
			return;
		}
		Property consume = new Property(GameConfig.GAME_ITEM_HATE, BigInteger.ONE);
		if(!player.getModule(CurrencyModule.class).currencyIsEnough(consume)){
			ret = GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
			return;
		}
		//预扣
		player.getModule(PreReduceModule.class).preReduce(consume);
		interactiveModule.addOpHateUserId(hateUserId);

		//发往跨服
		PlayerProto.CrossHatePlayerReqMsg.Builder crossMsg = PlayerProto.CrossHatePlayerReqMsg.newBuilder();
		crossMsg.setUserId(player.getUserId());
		crossMsg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId())));
		crossMsg.setHateUserId(hateUserId);
		crossMsg.setHateServerId(hateServerId);
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_HATE_PLAYER, crossMsg);
		GamePlayerMgr.sendPacket(player.getUserId(), pbMsg);

		needResponse = false;
	}

	@Override
	public void sendData(GamePlayer player) {
		if(needResponse) {
			PlayerProto.HatePlayerRespMsg.Builder respMsg = PlayerProto.HatePlayerRespMsg.newBuilder();
			respMsg.setRet(ret);
			if (0 == ret) {
				respMsg.setHeartCount(heartCount);
				respMsg.setEarnSpeed(hateUserInfo.getEarnSpeed().toString());
				respMsg.setEffectValue(effectValue.toString());
			}
			player.sendPacket(Protocol.U_HATE_PLAYER, respMsg);
		}
	}
}
